package com.sapitest.keywords;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Reporter;

/**
 * @date 2019-01-13
 * @author Liuxu
 * @version 1.0.1
 * @since jdk1.8
 */
public class JSONOperation {
    private static final Logger logger = LoggerFactory.getLogger(JSONOperation.class);

    /**
     * 获取JSONObject，并转换为字符串
     * @param text  原始JSONObject或者JSONArray
     * @param key   如果是JSONObject，key值为字符串；如果是JSONArray，key值为index，可转换为int的字符串
     * @return  JSONObject.toJSONString()
     */
    public static String getJSONObjectString(String text, String key){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            if (text.startsWith("{") && text.endsWith("}")){
                JSONObject jsonObject = JSON.parseObject(text);
                return jsonObject.getJSONObject(key).toJSONString();
            }else if (text.startsWith("[") && text.endsWith("]")){
                JSONArray jsonArray = JSON.parseArray(text);
                return jsonArray.getJSONObject(Integer.valueOf(key)).toJSONString();
            }else {
                Reporter.log("不是JSONObject或者JSONArray", true);
                logger.info("Not JSONObject or JSONArray, getJSONObjectString failed." + text);
            }
        } catch (JSONException | ClassCastException e){
            Reporter.log("转换JSONObject或者JSONArray失败", true);
            logger.error(e + "cast to JSONObject or JSONArray failed.");
        }
        return text;
    }

    /**
     * 获取JSONArray，并转换为字符串
     * @param text  原始JSONObject或者JSONArray
     * @param key   如果是JSONObject，key值为字符串；如果是JSONArray，key值为index，可转换为int的字符串
     * @return  JSONArray.toJSONString()
     */
    public static String getJSONArrayString(String text, String key){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            if (text.startsWith("{") && text.endsWith("}")){
                JSONObject jsonObject = JSON.parseObject(text);
                return jsonObject.getJSONArray(key).toJSONString();
            }else if (text.startsWith("[") && text.endsWith("]")){
                JSONArray jsonArray = JSON.parseArray(text);
                return jsonArray.getJSONArray(Integer.valueOf(key)).toJSONString();
            }else {
                Reporter.log("不是JSONObject或者JSONArray", true);
                logger.info("Not JSONObject or JSONArray, getJSONObjectString failed." + text);
            }
        }catch (JSONException | ClassCastException e){
            Reporter.log("转换JSONObject或者JSONArray失败", true);
            logger.error(e + "cast to JSONObject or JSONArray failed.");
        }
        return text;
    }

    /**
     * 根据key获取其value
     * @param text  可转换为JSONObject的字符串
     * @param key   key
     * @return  value
     */
    public static String getValue(String text, String key){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            return jsonObject.getString(key);
        } catch (JSONException e){
            Reporter.log("转换JSONObject失败", true);
            logger.error(e + "cast to JSONObject failed.");
        }
        return text;
    }

    /**
     * 增加一组键值对，并返回新的JSONObject
     * @param text  转换为JSONObject的字符串
     * @param key String
     * @param value Object
     * @return  增加一组键值对后的JSONObject
     */
    public static String fluentPut(String text, String key, Object value){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            return jsonObject.fluentPut(key, value).toJSONString();
        } catch (JSONException e){
            Reporter.log("转换JSONObject失败", true);
            logger.error(e + "cast to JSONObject failed.");
        }
        return text;
    }

    /**
     * 移除一组键值对，并返回新的JSONObject
     * @param text  转换为JSONObject的字符串
     * @param key key
     * @return  移除一组键值对后的JSONObject
     */
    public static String fluentRemove(String text, String key){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            return jsonObject.fluentRemove(key).toJSONString();
        } catch (JSONException e){
            Reporter.log("转换JSONObject失败", true);
            logger.error(e + "cast to JSONObject failed.");
        }
        return "";
    }

    /**
     * 移除多组键值对，并返回新的JSONObject
     * @param text  转换为JSONObject的字符串
     * @param keys 多个key以","隔开，例如：key1,key2,key3,...
     * @return  移除多组键值对后的JSONObject
     */
    public static String fluentRemoveAll(String text, String keys){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            String[] lists = keys.split(",");
            for (String list:lists) {
                jsonObject = jsonObject.fluentRemove(list);
            }
            return jsonObject.toJSONString();
        } catch (JSONException e){
            Reporter.log("转换JSONObject失败", true);
            logger.error(e + "cast to JSONObject failed.");
        }
        return "";
    }

    public static String parseObjectString(Object o){
        return JSONObject.toJSONString(o, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 将JSONObject或者JSONArray其中的一个键更新为JSONObject类型，并返回新的JSONObject或者JSONArray字符串
     * @param text  原始JSONObject或者JSONArray
     * @param key   添加或者修改的key值
     * @param value 对应的value值，需要能够转换为JSONObject，否在抛异常
     * @return  添加或者修改之后的JSONObject或者JSONArray
     */
    public static String fluentPutJSONObject(String text, String key, String value){
        if ("".equals(text)) {
            return text;
        }
        if (null == text){
            return text;
        }
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            JSONObject newvalue = JSON.parseObject(value);
            return jsonObject.fluentPut(key, newvalue).toJSONString();
        } catch (JSONException e) {
            Reporter.log("转换JSONObject失败", true);
            logger.error(e + "cast to JSONObject failed.");
        }
        return text;
    }

}
